તમારી ગ્લોબલ એપ્લિકેશન્સમાં બિનજરૂરી રી-રેન્ડર્સ ટાળીને અને પર્ફોર્મન્સ સુધારીને, કાર્યક્ષમ, ફાઇન-ગ્રેઇન્ડ અપડેટ્સ માટે રિએક્ટ કન્ટેક્સ્ટ સબ્સ્ક્રિપ્શનમાં માસ્ટરી મેળવો.
રિએક્ટ કન્ટેક્સ્ટ સબ્સ્ક્રિપ્શન: ગ્લોબલ એપ્લિકેશન્સ માટે ફાઇન-ગ્રેઇન્ડ અપડેટ કંટ્રોલ
આધુનિક વેબ ડેવલપમેન્ટના ગતિશીલ પરિદ્રશ્યમાં, કાર્યક્ષમ સ્ટેટ મેનેજમેન્ટ સર્વોપરી છે. જેમ જેમ એપ્લિકેશન્સ જટિલતામાં વધે છે, ખાસ કરીને જે ગ્લોબલ યુઝર બેઝ ધરાવે છે, ત્યારે એ સુનિશ્ચિત કરવું કે કમ્પોનન્ટ્સ ફક્ત જરૂરી હોય ત્યારે જ રી-રેન્ડર થાય, તે એક નિર્ણાયક પર્ફોર્મન્સની ચિંતા બની જાય છે. રિએક્ટની કન્ટેક્સ્ટ API પ્રોપ ડ્રિલિંગ વિના તમારા કમ્પોનન્ટ ટ્રીમાં સ્ટેટ શેર કરવાની એક શક્તિશાળી રીત પ્રદાન કરે છે. જોકે, એક સામાન્ય ભૂલ એ છે કે કન્ટેક્સ્ટનો ઉપયોગ કરતા કમ્પોનન્ટ્સમાં બિનજરૂરી રી-રેન્ડર્સ ટ્રિગર થાય છે, ભલેને શેર્ડ સ્ટેટનો માત્ર એક નાનો ભાગ બદલાયો હોય. આ પોસ્ટ રિએક્ટ કન્ટેક્સ્ટ સબ્સ્ક્રિપ્શન્સમાં ફાઇન-ગ્રેઇન્ડ અપડેટ કંટ્રોલની કળામાં ઊંડાણપૂર્વક ઉતરે છે, જે તમને વધુ પર્ફોર્મન્ટ અને સ્કેલેબલ ગ્લોબલ એપ્લિકેશન્સ બનાવવામાં સશક્ત બનાવે છે.
રિએક્ટ કન્ટેક્સ્ટ અને તેના રી-રેન્ડર વર્તનને સમજવું
રિએક્ટ કન્ટેક્સ્ટ દરેક સ્તરે મેન્યુઅલી પ્રોપ્સ પાસ કર્યા વિના કમ્પોનન્ટ ટ્રી દ્વારા ડેટા પસાર કરવા માટે એક મિકેનિઝમ પ્રદાન કરે છે. તે ત્રણ મુખ્ય ભાગોથી બનેલું છે:
- કન્ટેક્સ્ટ બનાવવું (Context Creation): કન્ટેક્સ્ટ ઓબ્જેક્ટ બનાવવા માટે
React.createContext()નો ઉપયોગ કરવો. - પ્રોવાઇડર (Provider): એક કમ્પોનન્ટ જે તેના વંશજોને કન્ટેક્સ્ટ વેલ્યુ પ્રદાન કરે છે.
- કન્ઝ્યુમર (Consumer): એક કમ્પોનન્ટ જે કન્ટેક્સ્ટ ફેરફારો માટે સબ્સ્ક્રાઇબ કરે છે. ઐતિહાસિક રીતે, આ
Context.Consumerકમ્પોનન્ટ સાથે કરવામાં આવતું હતું, પરંતુ હવે સામાન્ય રીતે, તેuseContextહૂકનો ઉપયોગ કરીને પ્રાપ્ત થાય છે.
મુખ્ય પડકાર એ છે કે રિએક્ટની કન્ટેક્સ્ટ API અપડેટ્સને કેવી રીતે હેન્ડલ કરે છે. જ્યારે કન્ટેક્સ્ટ પ્રોવાઇડર દ્વારા પ્રદાન કરેલ વેલ્યુ બદલાય છે, ત્યારે તે કન્ટેક્સ્ટનો ઉપયોગ કરતા બધા કમ્પોનન્ટ્સ (સીધા કે આડકતરી રીતે) ડિફોલ્ટ રૂપે રી-રેન્ડર થશે. આ વર્તન નોંધપાત્ર પર્ફોર્મન્સ અવરોધો તરફ દોરી શકે છે, ખાસ કરીને મોટી એપ્લિકેશન્સમાં અથવા જ્યારે કન્ટેક્સ્ટ વેલ્યુ જટિલ હોય અને વારંવાર અપડેટ થતી હોય. એક ગ્લોબલ થીમ પ્રોવાઇડરની કલ્પના કરો જ્યાં ફક્ત પ્રાથમિક રંગ બદલાય છે. યોગ્ય ઓપ્ટિમાઇઝેશન વિના, થીમ કન્ટેક્સ્ટને સાંભળતો દરેક કમ્પોનન્ટ રી-રેન્ડર થશે, ભલે તે ફક્ત ફોન્ટ ફેમિલીનો ઉપયોગ કરતો હોય.
સમસ્યા: `useContext` સાથે વ્યાપક રી-રેન્ડર્સ
ચાલો એક સામાન્ય દૃશ્ય સાથે ડિફોલ્ટ વર્તનને સમજાવીએ. ધારો કે આપણી પાસે યુઝર પ્રોફાઇલ કન્ટેક્સ્ટ છે જે યુઝરની વિવિધ માહિતી ધરાવે છે: નામ, ઇમેઇલ, પસંદગીઓ અને નોટિફિકેશન કાઉન્ટ. ઘણા કમ્પોનન્ટ્સને આ ડેટાની ઍક્સેસની જરૂર પડી શકે છે.
// UserContext.js
import React, { createContext, useState, useContext } from 'react';
const UserContext = createContext();
export const UserProvider = ({ children }) => {
const [user, setUser] = useState({
name: 'Global Citizen',
email: 'citizen@example.com',
preferences: { theme: 'dark', language: 'en' },
notificationCount: 0,
});
const updateNotificationCount = (count) => {
setUser(prevUser => ({ ...prevUser, notificationCount: count }));
};
return (
{children}
);
};
export const useUser = () => useContext(UserContext);
હવે, આ કન્ટેક્સ્ટનો ઉપયોગ કરતા બે કમ્પોનન્ટ્સનો વિચાર કરો:
// UserNameDisplay.js
import React from 'react';
import { useUser } from './UserContext';
const UserNameDisplay = () => {
const { user } = useUser();
console.log('UserNameDisplay rendered');
return User Name: {user.name};
};
export default UserNameDisplay;
// UserNotificationCount.js
import React from 'react';
import { useUser } from './UserContext';
const UserNotificationCount = () => {
const { user, updateNotificationCount } = useUser();
console.log('UserNotificationCount rendered');
return (
Notifications: {user.notificationCount}
);
};
export default UserNotificationCount;
તમારા મુખ્ય App કમ્પોનન્ટમાં:
// App.js
import React from 'react';
import { UserProvider } from './UserContext';
import UserNameDisplay from './UserNameDisplay';
import UserNotificationCount from './UserNotificationCount';
function App() {
return (
Global User Dashboard
{/* Other components that might consume UserContext or not */}
);
}
export default App;
જ્યારે તમે UserNotificationCount માં "Add Notification" બટન પર ક્લિક કરો છો, ત્યારે UserNotificationCount અને UserNameDisplay બંને રી-રેન્ડર થશે, ભલે UserNameDisplay ફક્ત યુઝરના નામની જ કાળજી લેતું હોય અને નોટિફિકેશન કાઉન્ટમાં તેને કોઈ રસ ન હોય. આ એટલા માટે છે કારણ કે કન્ટેક્સ્ટ વેલ્યુમાં આખું user ઓબ્જેક્ટ અપડેટ થયું છે, જે UserContext ના બધા કન્ઝ્યુમર્સ માટે રી-રેન્ડર ટ્રિગર કરે છે.
ફાઇન-ગ્રેઇન્ડ અપડેટ્સ માટે વ્યૂહરચનાઓ
ફાઇન-ગ્રેઇન્ડ અપડેટ્સ પ્રાપ્ત કરવાની ચાવી એ સુનિશ્ચિત કરવાની છે કે કમ્પોનન્ટ્સ ફક્ત તે જ સ્ટેટના ટુકડાઓ માટે સબ્સ્ક્રાઇબ કરે જેની તેમને જરૂર છે. અહીં કેટલીક અસરકારક વ્યૂહરચનાઓ છે:
1. કન્ટેક્સ્ટને વિભાજિત કરવું
સૌથી સીધો અને ઘણીવાર સૌથી અસરકારક અભિગમ એ છે કે તમારા કન્ટેક્સ્ટને નાના, વધુ કેન્દ્રિત કન્ટેક્સ્ટમાં વિભાજીત કરવું. જો તમારી એપ્લિકેશનના જુદા જુદા ભાગોને ગ્લોબલ સ્ટેટના જુદા જુદા સ્લાઇસની જરૂર હોય, તો તેમના માટે અલગ કન્ટેક્સ્ટ બનાવો.
ચાલો પાછલા ઉદાહરણને રિફેક્ટર કરીએ:
// UserProfileContext.js
import React, { createContext, useContext } from 'react';
const UserProfileContext = createContext();
export const UserProfileProvider = ({ children, profileData }) => {
return (
{children}
);
};
export const useUserProfile = () => useContext(UserProfileContext);
// UserNotificationsContext.js
import React, { createContext, useContext, useState } from 'react';
const UserNotificationsContext = createContext();
export const UserNotificationsProvider = ({ children }) => {
const [notificationCount, setNotificationCount] = useState(0);
const addNotification = () => {
setNotificationCount(prev => prev + 1);
};
return (
{children}
);
};
export const useUserNotifications = () => useContext(UserNotificationsContext);
અને તમે આનો ઉપયોગ કેવી રીતે કરશો:
// App.js
import React from 'react';
import { UserProfileProvider } from './UserProfileContext';
import { UserNotificationsProvider } from './UserNotificationsContext';
import UserNameDisplay from './UserNameDisplay'; // Still uses useUserProfile
import UserNotificationCount from './UserNotificationCount'; // Now uses useUserNotifications
function App() {
const initialProfileData = {
name: 'Global Citizen',
email: 'citizen@example.com',
preferences: { theme: 'dark', language: 'en' },
};
return (
Global User Dashboard
);
}
export default App;
// UserNameDisplay.js (updated to use UserProfileContext)
import React from 'react';
import { useUserProfile } from './UserProfileContext';
const UserNameDisplay = () => {
const userProfile = useUserProfile();
console.log('UserNameDisplay rendered');
return User Name: {userProfile.name};
};
export default UserNameDisplay;
// UserNotificationCount.js (updated to use UserNotificationsContext)
import React from 'react';
import { useUserNotifications } from './UserNotificationsContext';
const UserNotificationCount = () => {
const { notificationCount, addNotification } = useUserNotifications();
console.log('UserNotificationCount rendered');
return (
Notifications: {notificationCount}
);
};
export default UserNotificationCount;
આ વિભાજન સાથે, જ્યારે નોટિફિકેશન કાઉન્ટ બદલાય છે, ત્યારે ફક્ત UserNotificationCount જ રી-રેન્ડર થશે. UserNameDisplay, જે UserProfileContext ને સબ્સ્ક્રાઇબ કરે છે, તે રી-રેન્ડર નહીં થાય કારણ કે તેની કન્ટેક્સ્ટ વેલ્યુ બદલાઈ નથી. આ પર્ફોર્મન્સ માટે એક નોંધપાત્ર સુધારો છે.
ગ્લોબલ વિચારણાઓ: ગ્લોબલ એપ્લિકેશન માટે કન્ટેક્સ્ટને વિભાજીત કરતી વખતે, ચિંતાઓના તાર્કિક વિભાજનને ધ્યાનમાં લો. ઉદાહરણ તરીકે, ગ્લોબલ શોપિંગ કાર્ટમાં વસ્તુઓ, કુલ કિંમત અને ચેકઆઉટ સ્ટેટસ માટે અલગ કન્ટેક્સ્ટ હોઈ શકે છે. આ એ દર્શાવે છે કે કેવી રીતે ગ્લોબલ કોર્પોરેશનમાં જુદા જુદા વિભાગો તેમના ડેટાને સ્વતંત્ર રીતે સંચાલિત કરે છે.
2. `React.memo` અને `useCallback`/`useMemo` સાથે મેમોઇઝેશન
જ્યારે તમારી પાસે એક જ કન્ટેક્સ્ટ હોય ત્યારે પણ, તમે તેનો ઉપયોગ કરતા કમ્પોનન્ટ્સને મેમોઇઝ કરીને ઓપ્ટિમાઇઝ કરી શકો છો. React.memo એક હાયર-ઓર્ડર કમ્પોનન્ટ છે જે તમારા કમ્પોનન્ટને મેમોઇઝ કરે છે. તે કમ્પોનન્ટના પાછલા અને નવા પ્રોપ્સની શેલો કમ્પેરિઝન કરે છે. જો તે સમાન હોય, તો રિએક્ટ કમ્પોનન્ટને રી-રેન્ડર કરવાનું છોડી દે છે.
જોકે, useContext પરંપરાગત અર્થમાં પ્રોપ્સ પર કામ કરતું નથી; તે કન્ટેક્સ્ટ વેલ્યુના ફેરફારોના આધારે રી-રેન્ડર ટ્રિગર કરે છે. જ્યારે કન્ટેક્સ્ટ વેલ્યુ બદલાય છે, ત્યારે તેનો ઉપયોગ કરતો કમ્પોનન્ટ અસરકારક રીતે રી-રેન્ડર થાય છે. કન્ટેક્સ્ટ સાથે React.memo નો અસરકારક રીતે લાભ લેવા માટે, તમારે ખાતરી કરવાની જરૂર છે કે કમ્પોનન્ટ કન્ટેક્સ્ટમાંથી ડેટાના ચોક્કસ ટુકડાઓ પ્રોપ્સ તરીકે મેળવે છે અથવા કન્ટેક્સ્ટ વેલ્યુ પોતે જ સ્થિર છે.
એક વધુ એડવાન્સ્ડ પેટર્નમાં તમારા કન્ટેક્સ્ટ પ્રોવાઇડરમાં સિલેક્ટર ફંક્શન્સ બનાવવાનો સમાવેશ થાય છે. આ સિલેક્ટર્સ કન્ઝ્યુમર કમ્પોનન્ટ્સને સ્ટેટના ચોક્કસ સ્લાઇસ પર સબ્સ્ક્રાઇબ કરવાની મંજૂરી આપે છે, અને પ્રોવાઇડરને ફક્ત ત્યારે જ સબ્સ્ક્રાઇબર્સને સૂચિત કરવા માટે ઓપ્ટિમાઇઝ કરી શકાય છે જ્યારે તેમના ચોક્કસ સ્લાઇસમાં ફેરફાર થાય છે. આ ઘણીવાર કસ્ટમ હુક્સ દ્વારા અમલમાં મુકાય છે જે useContext અને `useMemo` નો લાભ લે છે.
ચાલો સિંગલ કન્ટેક્સ્ટ ઉદાહરણ પર પાછા જઈએ, પરંતુ કન્ટેક્સ્ટને વિભાજીત કર્યા વિના વધુ ગ્રેન્યુલર અપડેટ્સનું લક્ષ્ય રાખીએ:
// UserContextImproved.js
import React, { createContext, useContext, useState, useMemo, useCallback } from 'react';
const UserContext = createContext();
export const UserProvider = ({ children }) => {
const [user, setUser] = useState({
name: 'Global Citizen',
email: 'citizen@example.com',
preferences: { theme: 'dark', language: 'en' },
notificationCount: 0,
});
// Memoize the specific parts of the state if they are passed down as props
// or if you create custom hooks that consume specific parts.
const updateNotificationCount = useCallback((count) => {
setUser(prevUser => {
// Create a new user object only if notificationCount changes
if (prevUser.notificationCount === count) return prevUser;
return {
...prevUser,
notificationCount: count,
};
});
}, []);
// Provide specific selectors/values that are stable or only update when needed
const contextValue = useMemo(() => ({
user: {
name: user.name,
email: user.email,
preferences: user.preferences
// Exclude notificationCount from this memoized value if possible
},
notificationCount: user.notificationCount,
updateNotificationCount
}), [user.name, user.email, user.preferences, user.notificationCount, updateNotificationCount]);
return (
{children}
);
};
// Custom hooks for specific slices of the context
export const useUserName = () => {
const { user } = useContext(UserContext);
// `React.memo` on consuming component will work if `user.name` is stable
return user.name;
};
export const useUserNotifications = () => {
const { notificationCount, updateNotificationCount } = useContext(UserContext);
// `React.memo` on consuming component will work if `notificationCount` and `updateNotificationCount` are stable
return { notificationCount, updateNotificationCount };
};
હવે, આ ગ્રેન્યુલર હુક્સનો ઉપયોગ કરવા માટે કન્ઝ્યુમિંગ કમ્પોનન્ટ્સને રિફેક્ટર કરો:
// UserNameDisplay.js
import React from 'react';
import { useUserName } from './UserContextImproved';
const UserNameDisplay = React.memo(() => {
const userName = useUserName();
console.log('UserNameDisplay rendered');
return User Name: {userName};
});
export default UserNameDisplay;
// UserNotificationCount.js
import React from 'react';
import { useUserNotifications } from './UserContextImproved';
const UserNotificationCount = React.memo(() => {
const { notificationCount, updateNotificationCount } = useUserNotifications();
console.log('UserNotificationCount rendered');
return (
Notifications: {notificationCount}
);
});
export default UserNotificationCount;
આ સુધારેલા સંસ્કરણમાં:
- `useCallback` નો ઉપયોગ
updateNotificationCountજેવા ફંક્શન્સ માટે થાય છે જેથી ખાતરી કરી શકાય કે તેમની ઓળખ રી-રેન્ડર્સ દરમિયાન સ્થિર રહે, જે ચાઇલ્ડ કમ્પોનન્ટ્સમાં બિનજરૂરી રી-રેન્ડર્સને અટકાવે છે જે તેમને પ્રોપ્સ તરીકે મેળવે છે. - `useMemo` નો ઉપયોગ પ્રોવાઇડરની અંદર મેમોઇઝ્ડ કન્ટેક્સ્ટ વેલ્યુ બનાવવા માટે થાય છે. આ મેમોઇઝ્ડ ઓબ્જેક્ટમાં ફક્ત જરૂરી સ્ટેટના ટુકડાઓ (અથવા તારવેલી વેલ્યુ) નો સમાવેશ કરીને, અમે સંભવિતપણે કન્ઝ્યુમર્સને નવી કન્ટેક્સ્ટ વેલ્યુ રેફરન્સ મળવાની સંખ્યા ઘટાડી શકીએ છીએ. નિર્ણાયક રીતે, અમે કસ્ટમ હુક્સ (
useUserName,useUserNotifications) બનાવીએ છીએ જે કન્ટેક્સ્ટના ચોક્કસ ભાગોને બહાર કાઢે છે. - `React.memo` કન્ઝ્યુમર કમ્પોનન્ટ્સ પર લાગુ કરવામાં આવે છે. કારણ કે આ કમ્પોનન્ટ્સ હવે સ્ટેટના માત્ર ચોક્કસ ભાગનો જ ઉપયોગ કરે છે (દા.ત.,
userNameઅથવાnotificationCount), અને આ વેલ્યુઝ મેમોઇઝ્ડ છે અથવા ફક્ત ત્યારે જ અપડેટ થાય છે જ્યારે તેમનો ચોક્કસ ડેટા બદલાય છે,React.memoઅસરકારક રીતે રી-રેન્ડર્સને અટકાવી શકે છે જ્યારે કન્ટેક્સ્ટમાં અસંબંધિત સ્ટેટ બદલાય છે.
જ્યારે તમે બટન પર ક્લિક કરો છો, ત્યારે user.notificationCount બદલાય છે. જોકે, પ્રોવાઇડરને પાસ થયેલ `contextValue` ઓબ્જેક્ટ ફરીથી બનાવી શકાય છે. ચાવી એ છે કે useUserName હૂક `user.name` મેળવે છે, જે બદલાયું નથી. જો UserNameDisplay કમ્પોનન્ટ React.memo માં લપેટાયેલું હોય અને તેના પ્રોપ્સ (આ કિસ્સામાં, useUserName દ્વારા પરત કરેલ વેલ્યુ) બદલાયા ન હોય, તો તે રી-રેન્ડર નહીં થાય. તેવી જ રીતે, UserNotificationCount રી-રેન્ડર થાય છે કારણ કે તેના સ્ટેટનો ચોક્કસ સ્લાઇસ (notificationCount) બદલાયો છે.
ગ્લોબલ વિચારણાઓ: આ ટેકનિક UI થીમ્સ અથવા આંતરરાષ્ટ્રીયકરણ (i18n) સેટિંગ્સ જેવી ગ્લોબલ કન્ફિગરેશન્સ માટે ખાસ કરીને મૂલ્યવાન છે. જો કોઈ યુઝર તેની પસંદગીની ભાષા બદલે છે, તો ફક્ત તે જ કમ્પોનન્ટ્સ કે જે સક્રિયપણે સ્થાનિકીકૃત ટેક્સ્ટ પ્રદર્શિત કરે છે, તે જ રી-રેન્ડર થવા જોઈએ, નહીં કે દરેક કમ્પોનન્ટ જેને આખરે લોકેલ ડેટાની ઍક્સેસની જરૂર પડી શકે છે.
3. કસ્ટમ કન્ટેક્સ્ટ સિલેક્ટર્સ (એડવાન્સ્ડ)
અત્યંત જટિલ સ્ટેટ સ્ટ્રક્ચર્સ માટે અથવા જ્યારે તમને વધુ અત્યાધુનિક નિયંત્રણની જરૂર હોય, ત્યારે તમે કસ્ટમ કન્ટેક્સ્ટ સિલેક્ટર્સ લાગુ કરી શકો છો. આ પેટર્નમાં એક હાયર-ઓર્ડર કમ્પોનન્ટ અથવા કસ્ટમ હૂક બનાવવાનો સમાવેશ થાય છે જે દલીલ તરીકે સિલેક્ટર ફંક્શન લે છે. હૂક પછી કન્ટેક્સ્ટ પર સબ્સ્ક્રાઇબ કરે છે, પરંતુ ફક્ત ત્યારે જ કન્ઝ્યુમિંગ કમ્પોનન્ટને રી-રેન્ડર કરે છે જ્યારે સિલેક્ટર ફંક્શન દ્વારા પરત કરેલ વેલ્યુ બદલાય છે.
આ Zustand અથવા Redux જેવી લાઇબ્રેરીઓ તેમના સિલેક્ટર્સ સાથે જે પ્રાપ્ત કરે છે તેના જેવું જ છે. તમે આ વર્તનની નકલ કરી શકો છો:
// UserContextSelectors.js
import React, { createContext, useContext, useState, useMemo, useCallback, useRef, useEffect } from 'react';
const UserContext = createContext();
export const UserProvider = ({ children }) => {
const [user, setUser] = useState({
name: 'Global Citizen',
email: 'citizen@example.com',
preferences: { theme: 'dark', language: 'en' },
notificationCount: 0,
});
const updateNotificationCount = useCallback((count) => {
setUser(prevUser => {
if (prevUser.notificationCount === count) return prevUser;
return {
...prevUser,
notificationCount: count,
};
});
}, []);
// The entire user object is the value for simplicity here,
// but the custom hook handles selection.
const contextValue = useMemo(() => ({ user, updateNotificationCount }), [user, updateNotificationCount]);
return (
{children}
);
};
// Custom hook with selection
export const useUserContext = (selector) => {
const context = useContext(UserContext);
if (!context) {
throw new Error('useUserContext must be used within a UserProvider');
}
const { user, updateNotificationCount } = context;
// Memoize the selected value to prevent unnecessary re-renders
const selectedValue = useMemo(() => selector(user), [user, selector]);
// Use a ref to track the previous selected value
const previousSelectedValue = useRef();
useEffect(() => {
previousSelectedValue.current = selectedValue;
}, [selectedValue]);
// Only re-render if the selected value has changed.
// React.memo on the consuming component combined with this
// ensures efficient updates.
const isSelectedValueDifferent = selectedValue !== previousSelectedValue.current;
return {
selectedValue,
updateNotificationCount,
// This is a simplified mechanism. A robust solution would involve
// a more complex subscription manager within the provider.
// For demonstration, we rely on the consuming component's memoization.
};
};
કન્ઝ્યુમિંગ કમ્પોનન્ટ્સ આના જેવા દેખાશે:
// UserNameDisplay.js
import React from 'react';
import { useUserContext } from './UserContextSelectors';
const UserNameDisplay = React.memo(() => {
// Selector function for user name
const userNameSelector = (user) => user.name;
const { selectedValue: userName } = useUserContext(userNameSelector);
console.log('UserNameDisplay rendered');
return User Name: {userName};
});
export default UserNameDisplay;
// UserNotificationCount.js
import React from 'react';
import { useUserContext } from './UserContextSelectors';
const UserNotificationCount = React.memo(() => {
// Selector function for notification count and the update function
const notificationSelector = (user) => ({ count: user.notificationCount });
const { selectedValue, updateNotificationCount } = useUserContext(notificationSelector);
console.log('UserNotificationCount rendered');
return (
Notifications: {selectedValue.count}
);
});
export default UserNotificationCount;
આ પેટર્નમાં:
useUserContextહૂક એકselectorફંક્શન લે છે.- તે કન્ટેક્સ્ટના આધારે પસંદ કરેલ વેલ્યુની ગણતરી કરવા માટે
useMemoનો ઉપયોગ કરે છે. આ પસંદ કરેલ વેલ્યુ મેમોઇઝ્ડ છે. useEffectઅને `useRef` નો સંયોગ એ સુનિશ્ચિત કરવાની એક સરળ રીત છે કે કમ્પોનન્ટ ફક્ત ત્યારે જ રી-રેન્ડર થાય જોselectedValueખરેખર બદલાય. એક સાચી મજબૂત અમલીકરણમાં પ્રોવાઇડરની અંદર વધુ અત્યાધુનિક સબ્સ્ક્રિપ્શન મેનેજમેન્ટ સિસ્ટમનો સમાવેશ થશે, જ્યાં કન્ઝ્યુમર્સ તેમના સિલેક્ટર્સની નોંધણી કરે છે અને પ્રોવાઇડર તેમને પસંદગીપૂર્વક સૂચિત કરે છે.React.memoમાં લપેટાયેલા કન્ઝ્યુમિંગ કમ્પોનન્ટ્સ, ફક્ત ત્યારે જ રી-રેન્ડર થશે જો તેમના ચોક્કસ સિલેક્ટર ફંક્શન દ્વારા પરત કરેલ વેલ્યુ બદલાય.
ગ્લોબલ વિચારણાઓ: આ અભિગમ મહત્તમ લવચીકતા પ્રદાન કરે છે. ગ્લોબલ ઇ-કોમર્સ પ્લેટફોર્મ માટે, તમારી પાસે તમામ કાર્ટ-સંબંધિત ડેટા માટે એક જ કન્ટેક્સ્ટ હોઈ શકે છે પરંતુ ફક્ત પ્રદર્શિત કાર્ટ આઇટમ કાઉન્ટ, સબટોટલ, અથવા શિપિંગ ખર્ચને સ્વતંત્ર રીતે અપડેટ કરવા માટે સિલેક્ટર્સનો ઉપયોગ કરી શકો છો.
કઈ વ્યૂહરચનાનો ક્યારે ઉપયોગ કરવો
- કન્ટેક્સ્ટનું વિભાજન: આ સામાન્ય રીતે મોટાભાગના દૃશ્યો માટે પસંદગીની પદ્ધતિ છે. તે સ્વચ્છ કોડ, ચિંતાઓના વધુ સારા વિભાજન તરફ દોરી જાય છે, અને તેના વિશે તર્ક કરવો સરળ છે. જ્યારે તમારી એપ્લિકેશનના જુદા જુદા ભાગો સ્પષ્ટપણે ગ્લોબલ ડેટાના વિશિષ્ટ સમૂહો પર આધાર રાખે છે ત્યારે તેનો ઉપયોગ કરો.
- `React.memo`, `useCallback`, `useMemo` સાથે મેમોઇઝેશન (કસ્ટમ હુક્સ સાથે): આ એક સારી મધ્યવર્તી વ્યૂહરચના છે. તે મદદ કરે છે જ્યારે કન્ટેક્સ્ટનું વિભાજન વધુ પડતું લાગે છે, અથવા જ્યારે એક જ કન્ટેક્સ્ટ તાર્કિક રીતે ચુસ્તપણે જોડાયેલ ડેટા ધરાવે છે. તેને વધુ મેન્યુઅલ પ્રયત્નોની જરૂર છે પરંતુ એક જ કન્ટેક્સ્ટમાં ગ્રેન્યુલર કંટ્રોલ પ્રદાન કરે છે.
- કસ્ટમ કન્ટેક્સ્ટ સિલેક્ટર્સ: આને અત્યંત જટિલ એપ્લિકેશન્સ માટે અનામત રાખો જ્યાં ઉપરોક્ત પદ્ધતિઓ બોજારૂપ બને છે, અથવા જ્યારે તમે સમર્પિત સ્ટેટ મેનેજમેન્ટ લાઇબ્રેરીઓના અત્યાધુનિક સબ્સ્ક્રિપ્શન મોડેલ્સનું અનુકરણ કરવા માંગતા હોવ. તે સૌથી વધુ ફાઇન-ગ્રેઇન્ડ કંટ્રોલ પ્રદાન કરે છે પરંતુ વધેલી જટિલતા સાથે આવે છે.
ગ્લોબલ કન્ટેક્સ્ટ મેનેજમેન્ટ માટે શ્રેષ્ઠ પ્રથાઓ
રિએક્ટ કન્ટેક્સ્ટ સાથે ગ્લોબલ એપ્લિકેશન્સ બનાવતી વખતે, આ શ્રેષ્ઠ પ્રથાઓ ધ્યાનમાં લો:
- કન્ટેક્સ્ટ વેલ્યુઝને સરળ રાખો: મોટા, મોનોલિથિક કન્ટેક્સ્ટ ઓબ્જેક્ટ્સ ટાળો. તેમને તાર્કિક રીતે વિભાજીત કરો.
- કસ્ટમ હુક્સને પ્રાધાન્ય આપો: કન્ટેક્સ્ટ કન્ઝમ્પ્શનને કસ્ટમ હુક્સ (દા.ત.,
useUserProfile,useTheme) માં એબ્સ્ટ્રેક્ટ કરવાથી તમારા કમ્પોનન્ટ્સ સ્વચ્છ બને છે અને પુનઃઉપયોગિતાને પ્રોત્સાહન મળે છે. - `React.memo` નો વિવેકપૂર્ણ ઉપયોગ કરો: દરેક કમ્પોનન્ટને `React.memo` માં લપેટશો નહીં. તમારી એપ્લિકેશનનું પ્રોફાઇલ કરો અને તેને ફક્ત ત્યાં જ લાગુ કરો જ્યાં રી-રેન્ડર્સ પર્ફોર્મન્સની ચિંતાનો વિષય હોય.
- ફંક્શન્સની સ્થિરતા: અનિચ્છનીય રી-રેન્ડર્સને રોકવા માટે હંમેશા કન્ટેક્સ્ટ અથવા પ્રોપ્સ દ્વારા પાસ કરાયેલા ફંક્શન્સ માટે `useCallback` નો ઉપયોગ કરો.
- તારવેલા ડેટાને મેમોઇઝ કરો: કન્ટેક્સ્ટમાંથી તારવેલી કોઈપણ ગણતરી કરેલ વેલ્યુ માટે `useMemo` નો ઉપયોગ કરો જેનો ઉપયોગ બહુવિધ કમ્પોનન્ટ્સ દ્વારા કરવામાં આવે છે.
- થર્ડ-પાર્ટી લાઇબ્રેરીઓનો વિચાર કરો: ખૂબ જ જટિલ ગ્લોબલ સ્ટેટ મેનેજમેન્ટ જરૂરિયાતો માટે, Zustand, Jotai, અથવા Recoil જેવી લાઇબ્રેરીઓ ફાઇન-ગ્રેઇન્ડ સબ્સ્ક્રિપ્શન્સ અને સિલેક્ટર્સ માટે બિલ્ટ-ઇન સોલ્યુશન્સ પ્રદાન કરે છે, ઘણીવાર ઓછા બોઇલરપ્લેટ સાથે.
- તમારા કન્ટેક્સ્ટનું દસ્તાવેજીકરણ કરો: સ્પષ્ટપણે દસ્તાવેજ કરો કે દરેક કન્ટેક્સ્ટ શું પ્રદાન કરે છે અને કન્ઝ્યુમર્સે તેની સાથે કેવી રીતે ક્રિયાપ્રતિક્રિયા કરવી જોઈએ. ગ્લોબલ પ્રોજેક્ટ્સ પર કામ કરતી મોટી, વિતરિત ટીમો માટે આ નિર્ણાયક છે.
નિષ્કર્ષ
રિએક્ટ કન્ટેક્સ્ટમાં ફાઇન-ગ્રેઇન્ડ અપડેટ કંટ્રોલમાં માસ્ટરી મેળવવી એ પર્ફોર્મન્ટ, સ્કેલેબલ અને જાળવી શકાય તેવી ગ્લોબલ એપ્લિકેશન્સ બનાવવા માટે આવશ્યક છે. વ્યૂહાત્મક રીતે કન્ટેક્સ્ટને વિભાજીત કરીને, મેમોઇઝેશન ટેકનિકનો લાભ લઈને, અને કસ્ટમ સિલેક્ટર પેટર્ન ક્યારે લાગુ કરવી તે સમજીને, તમે બિનજરૂરી રી-રેન્ડર્સને નોંધપાત્ર રીતે ઘટાડી શકો છો અને ખાતરી કરી શકો છો કે તમારી એપ્લિકેશન તેના કદ અથવા તેના સ્ટેટની જટિલતાને ધ્યાનમાં લીધા વિના રિસ્પોન્સિવ રહે છે.
જેમ જેમ તમે જુદા જુદા પ્રદેશો, સમય ઝોન અને નેટવર્ક પરિસ્થિતિઓમાં યુઝર્સને સેવા આપતી એપ્લિકેશન્સ બનાવો છો, તેમ આ ઓપ્ટિમાઇઝેશન્સ ફક્ત શ્રેષ્ઠ પ્રથાઓ જ નહીં, પરંતુ જરૂરિયાતો બની જાય છે. તમારા ગ્લોબલ ઓડિયન્સ માટે શ્રેષ્ઠ યુઝર અનુભવ પ્રદાન કરવા માટે આ વ્યૂહરચનાઓ અપનાવો.